/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.incad.psh.pshassign.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.query.client.Function;
import static com.google.gwt.query.client.GQuery.$;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import cz.incad.psh.pshassign.client.res.Resources;
import cz.incad.psh.pshassign.client.rpc.PSHService;
import cz.incad.psh.pshassign.client.rpc.PSHServiceAsync;
import static gwtquery.plugins.ui.Ui.Ui;
import gwtquery.plugins.ui.widgets.Slider;
import java.util.HashMap;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author alberto
 */
public class Options extends Composite {

    private static OptionsUiBinder uiBinder = GWT.create(OptionsUiBinder.class);
    PSHServiceAsync pshService = GWT.create(PSHService.class);

    interface OptionsUiBinder extends UiBinder<Widget, Options> {
    }
    @UiField
    ScrollPanel scrollPanel;
    @UiField
    FlowPanel mixer;
    @UiField
    FlowPanel ops;
    @UiField
    HorizontalPanel assign_ops;
    @UiField
    Anchor save;
    
    HashMap<String, Label> sliders = new HashMap<String, Label>();
    HashMap<String, TextBox> boxes = new HashMap<String, TextBox>();
    HashMap<String, TextBox> spinners = new HashMap<String, TextBox>();
    boolean initialized = false;
    JSONObject config;
    MainPage mainPage;
    boolean slidersReady = false;

    public Options() {
        initWidget(uiBinder.createAndBindUi(this));

        scrollPanel.setPixelSize(780, 400);
        save.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                save();
            }
        });
    }
    
   public String getString(String section, String option) throws Exception{
      return config.get(section).isObject().get(option).isString().stringValue();
   }
    
   public double getDouble(String section, String option) throws Exception{
      return config.get(section).isObject().get(option).isNumber().doubleValue();
   }
    
   public int getInt(String section, String option) throws Exception{
      return (int) Math.round(config.get(section).isObject().get(option).isNumber().doubleValue());
   } 

    private void addSlider(String name, String key) {

        Double val = config.get("assign").isObject().get(key).isNumber().doubleValue();

        String value = NumberFormat.getFormat("0.0").format((val));


        //String value = props.get(key).isNumber().toString();
        FlowPanel fl = new FlowPanel();
        fl.getElement().setAttribute("id", "eq-" + key);
        Label caption = new Label(name);
        caption.setStyleName(Resources.INSTANCE.css().sliderLabel());
        fl.add(caption);
        

        FlowPanel sl = new FlowPanel();
        sl.getElement().setAttribute("class", "sl");

        fl.add(sl);
        Label tx = new Label();
        //tx.setName("i-" + key);
        tx.setText(value);
        //tx.setMaxLength(3);
        tx.getElement().setAttribute("value", value);
        tx.getElement().setAttribute("id", "i-" + key);
        
        tx.setStyleName(Resources.INSTANCE.css().sliderValue());
        fl.add(tx);
        mixer.add(fl);
        sliders.put(key, tx);
        //doSlider(name, val * 10);
    }

    private void doSliders() {
        Iterator it = sliders.keySet().iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            doSlider(key, NumberFormat.getFormat("0.0").parse(sliders.get(key).getText()));
        }
        slidersReady = true;
    }

    private void doSlider(final String id, Double val) {
        String value = NumberFormat.getFormat("0.0").format(val);
        $("#eq-" + id + " > div.sl").as(Ui).slider("{\n"
                + "            min: 0,\n"
                + "            max: 100,\n"
                + "            value: " + val + ",\n"
                + "            range: \"min\",\n"
                + "            animate: true,\n"
                + "            orientation: \"vertical\"\n"
                + "        }");

        $("#eq-" + id + " > div.sl").as(Ui).slider().bind("slide", new Function() {
            @Override
            public boolean f(Event e, Object data) {

                Slider.Event slideEvent = ((JavaScriptObject) data).cast();
                $("#i-" + id).html(NumberFormat.getFormat("0.0").format((slideEvent.floatValue())));

                return false;
            }
        });
    }

    private void close() {
        //pop.hide();
    }

    public void load() {
        if (!slidersReady) {
            doSliders();
        }
    }

    @Override
    protected void onLoad() {
        init();
    }

    private Widget addOption(String section, String key, String label) {
        String value = config.get(section).isObject().get(key).isString().stringValue();
        FlowPanel fl = new FlowPanel();
        TextBox tx = new TextBox();
        tx.setName("i-" + key);
        tx.setText(value);
        tx.setWidth("90%");

        tx.getElement().setAttribute("value", value);
        tx.getElement().setAttribute("id", "i-" + key);
        boxes.put(section + "/" + key, tx);
        fl.add(new Label(label));
        fl.add(tx);
        return fl;
    }

    private void save() {
        Iterator it = sliders.keySet().iterator();

        while (it.hasNext()) {
            String key = (String) it.next();
            //JSONValue jv = new JSONNumber(Double.parseDouble(sliders.get(key).getText()));
            JSONValue jv = new JSONNumber(NumberFormat.getFormat("0.0").parse(sliders.get(key).getText()));

            config.get("assign").isObject().put(key, jv);
        }

        it = boxes.keySet().iterator();
        while (it.hasNext()) {
            String kpar = (String) it.next();
            String[] par = kpar.split("/");
            String key = par[1];
            String section = par[0];
            JSONValue jv = new JSONString(boxes.get(kpar).getText());
            config.get(section).isObject().put(key, jv);
        }
        try {
            pshService.setOptions(config.toString(), new AsyncCallback() {
                @Override
                public void onFailure(Throwable caught) {
                    mixer.add(new InlineHTML("error setting configuration: "
                            + caught.getLocalizedMessage()));
                }

                @Override
                public void onSuccess(Object result) {
                    Window.alert("saved!");
                }
            });
        } catch (Exception ex) {
            Logger.getLogger(Options.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    
    private Widget addSpinner(String section, String key, String label) {

        Double val = config.get("assign").isObject().get(key).isNumber().doubleValue();

        String value = NumberFormat.getFormat("0").format((val));


        FlowPanel fl = new FlowPanel();
        TextBox tx = new TextBox();
        tx.setName("sp-" + key);
        tx.setText(value);
        tx.setWidth("25px");

        tx.getElement().setAttribute("value", value);
        tx.getElement().setAttribute("id", "sp-" + key);
        spinners.put(section + "/" + key, tx);
        
        fl.add(new Label(label));
        fl.add(tx);
        return fl;
    }
    
    private void addAssignOptions(){
        
        assign_ops.add(addSpinner("assign", "max_keys", "max keys"));
        //assign_ops.add(addSpinner("assign", "near", "vzdalenost"));
        assign_ops.add(addSpinner("assign", "boost_solr", "boost solr"));
        assign_ops.add(addSpinner("assign", "max_solr_keys", "max solr keys"));
                    
                    
    }

    public void init() {
        if (initialized) {
            return;
        }
        mixer.getElement().setAttribute("id", "eq");
        try {
            pshService.getOptions(new AsyncCallback() {
                @Override
                public void onFailure(Throwable caught) {
                    mixer.add(new InlineHTML("error getting configuration: "
                            + caught.getLocalizedMessage()));
                }

                @Override
                public void onSuccess(Object result) {

                    JSONValue value = JSONParser.parseStrict((String) result);
                    config = value.isObject();
                    addSlider("title", "boost_title");
                    addSlider("anotace", "boost_annotace");
                    addSlider("subject", "boost_subjects");
                    addSlider("konference", "boost_konference");
                    addSlider("csPref", "boost_csPrefLabel");
                    addSlider("enPref", "boost_enPrefLabel");
                    addSlider("csAlt", "boost_csAltLabel");
                    addSlider("enAlt", "boost_enAltLabel");
                    addSlider("level", "boost_level");
                    addSlider("proximity", "boost_proximity");
                    addSlider("exact", "boost_exact");

                    addAssignOptions();
                    
                    CaptionPanel cpc = new CaptionPanel("bibupload");
                    FlowPanel cp = new FlowPanel();
                    cpc.add(cp);
                    ops.add(cpc);
                    cp.add(addOption("bibupload", "adress", "bibUpload adress"));
                    cp.add(addOption("bibupload", "user_agent", "bibUpload user agent"));


                    cpc = new CaptionPanel("invenio");
                    cp = new FlowPanel();
                    cpc.add(cp);
                    ops.add(cpc);
                    cp.add(addOption("invenio", "oai_url", "OAI harvester url"));
                    cp.add(addOption("invenio", "oai_set", "OAI set"));
                    cp.add(addOption("invenio", "oai_metadataPrefix", "OAI metadataPrefix"));
                    cp.add(addOption("invenio", "oai_xsl", "xsl filaname"));
                    cp.add(addOption("invenio", "solr", "SOLR url"));

                    cpc = new CaptionPanel("PSH");
                    cp = new FlowPanel();
                    cpc.add(cp);
                    ops.add(cpc);
                    cp.add(addOption("psh", "xsl", "xsl file"));
                    cp.add(addOption("psh", "rdf", "rdf file (can be url file:/// or http://)"));
                    cp.add(addOption("psh", "solr", "SOLR url"));
                    initialized = true;
                }
            });
        } catch (Exception ex) {
            Logger.getLogger(Options.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
